/**
 * 自定义公共函数包
 * 这里可以写你自己的公共函数
 */
var pubFun = {};
class CryptoUtil {
    static KEY_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    static SALT_LENGTH = 16;
    static PRIVATE_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n" +
        "nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==";

    static base64UrlEncode(str) {
        return Buffer.from(str)
            .toString('base64')
            .replace(/\+/g, '-')
            .replace(/\//g, '_')
            .replace(/=+$/, '');
    }

    static base64UrlDecode(str) {
        str = str.replace(/-/g, '+').replace(/_/g, '/');
        while (str.length % 4) {
            str += '=';
        }
        return Buffer.from(str, 'base64').toString();
    }

    static encrypt(data, key) {
        let result = '';
        for (let i = 0; i < data.length; i++) {
            result += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
        }
        return this.base64UrlEncode(result);
    }

    static decrypt(encryptedData, key) {
        try {
            const data = this.base64UrlDecode(encryptedData);
            let result = '';
            for (let i = 0; i < data.length; i++) {
                result += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
            }
            return result;
        } catch (error) {
            console.error('Decrypt Error:', error);
            throw error;
        }
    }

    static decryptRequest(encryptedData, salt) {
        try {
            const decrypted = this.decrypt(encryptedData, this.PRIVATE_KEY + salt);
            return JSON.parse(decrypted);
        } catch (error) {
            console.error('Parse Request Error:', error);
            throw error;
        }
    }

    static encryptResponse(data, salt) {
        const jsonStr = JSON.stringify(data);
        return this.encrypt(jsonStr, this.PRIVATE_KEY + salt);
    }
}

// Express 中间件示例
function cryptoMiddleware(req, res, next) {
    const salt = req.headers['x-salt'];
    const encryptedData = req.body.data;

    try {
        // 解密请求数据
        req.decryptedBody = CryptoUtil.decryptRequest(encryptedData, salt);

        // 重写 res.json 方法以加密响应数据
        const originalJson = res.json;
        res.json = function(data) {
            const encryptedResponse = CryptoUtil.encryptResponse(data, salt);
            return originalJson.call(this, { data: encryptedResponse });
        };

        next();
    } catch (error) {
        console.error('Middleware Error:', error);
        res.status(400).json({ error: 'Invalid encrypted data' });
    }
}

/**
 * 公共函数写法示例
 * 调用示例：
 * pubFun.test();
 * 或
 * vk.myfn.test();
 */
pubFun.test = function(path) {
	// 可通过 uniCloud.vk 来获取vk实例
	let vk = uniCloud.vk;
	let timeStr = vk.pubfn.timeFormat(new Date(), "yyyy-MM-dd hh:mm:ss");
	// 逻辑
	// ...
	// 逻辑	
	return {
		timeStr,
		msg: "这是公共函数test的返回"
	}
}

pubFun.CryptoUtil = CryptoUtil;
pubFun.cryptoMiddleware = cryptoMiddleware
module.exports = pubFun;
